<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>延时发送串口数据工具</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            line-height: 1.6;
        }
        button {
            background-color: #4CAF50;
            border: none;
            color: white;
            padding: 10px 20px;
            text-align: center;
            text-decoration: none;
            display: inline-block;
            font-size: 16px;
            margin: 10px 2px;
            cursor: pointer;
            border-radius: 4px;
        }
        button:disabled {
            background-color: #cccccc;
            cursor: not-allowed;
        }
        #status {
            margin: 20px 0;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
            min-height: 20px;
        }
        .success {
            color: #4CAF50;
        }
        .error {
            color: #f44336;
        }
        .data-display {
            font-family: monospace;
            background-color: #f5f5f5;
            padding: 10px;
            border-radius: 4px;
            margin: 10px 0;
        }
        .command {
            margin: 15px 0;
            padding: 10px;
            border-left: 4px solid #4CAF50;
            background-color: #f9f9f9;
        }
        #countdown {
            font-size: 1.2em;
            font-weight: bold;
            color: #2c3e50;
            margin: 10px 0;
        }
    </style>
</head>
<body>
    <h1>延时发送串口数据工具</h1>
    <p>此工具将在点击按钮3秒后，依次发送两组固定16进制数据。</p>
    
    <div class="command">
        <h3>第一组数据 (3秒后发送):</h3>
        <div class="data-display">57 AB 00 02 08 00 00 04 00 00 00 00 00 10</div>
    </div>
    
    <div class="command">
        <h3>第二组数据 (紧随第一组发送):</h3>
        <div class="data-display">57 AB 00 02 08 00 00 00 00 00 00 00 00 0C</div>
    </div>
    
    <button id="connectBtn">连接串口</button>
    <button id="sendBtn" disabled>开始延时发送</button>
    <button id="disconnectBtn" disabled>断开连接</button>
    
    <div id="countdown"></div>
    
    <h2>状态</h2>
    <div id="status">未连接</div>
    
    <h2>接收数据</h2>
    <div id="receivedData" class="data-display">暂无数据</div>
    
    <script>
        let port;
        let reader;
        let countdownInterval;
        
        // 定义要发送的两组数据
        // const command1 = [0x57, 0xAB, 0x00, 0x02, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10];
        
        const command1 = [0x57, 0xAB, 0x00, 0x04, 0x07, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10]

        // const command1 = [
        //   0x57, 0xAB, 0x00, 0x02, 0x08, // 固定
        //   /** 8位 */
        //   0x02, // 控制键组合键
        //   0x00, // 固定
        //   0x04, 0x00, 0x00, 0x00, 0x00, 0x00, // 6个普通键，空用0x00占位
        //   0x12 // 累加
        // ];

        const command2 = [0x57, 0xAB, 0x00, 0x04, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F];
        
        // 获取DOM元素
        const connectBtn = document.getElementById('connectBtn');
        const sendBtn = document.getElementById('sendBtn');
        const disconnectBtn = document.getElementById('disconnectBtn');
        const statusDiv = document.getElementById('status');
        const receivedDataDiv = document.getElementById('receivedData');
        const countdownDiv = document.getElementById('countdown');
        
        // 连接串口按钮点击事件
        connectBtn.addEventListener('click', async () => {
            try {
                if (!('serial' in navigator)) {
                    throw new Error('您的浏览器不支持Web Serial API。请使用Chrome 89+或Edge 89+。');
                }
                
                port = await navigator.serial.requestPort();
                await port.open({ baudRate: 9600 });
                
                updateStatus('串口已连接', 'success');
                connectBtn.disabled = true;
                sendBtn.disabled = false;
                disconnectBtn.disabled = false;
                
                readData();
                
            } catch (error) {
                updateStatus(`错误: ${error.message}`, 'error');
                console.error('连接错误:', error);
            }
        });
        
        // 发送数据按钮点击事件
        sendBtn.addEventListener('click', async () => {
            if (!port) {
                updateStatus('请先连接串口', 'error');
                return;
            }
            
            try {
                sendBtn.disabled = true;
                let seconds = 3;
                
                // 开始倒计时
                countdownInterval = setInterval(() => {
                    countdownDiv.textContent = `将在 ${seconds} 秒后发送数据...`;
                    seconds--;
                    
                    if (seconds < 0) {
                        clearInterval(countdownInterval);
                        countdownDiv.textContent = '';
                        setInterval(() => {
                            executeDelayedSend();
                        }, 30 * 1000)
                    }
                }, 1000);
                
            } catch (error) {
                updateStatus(`发送错误: ${error.message}`, 'error');
                console.error('发送错误:', error);
                sendBtn.disabled = false;
            }
        });
        
        // 执行延时发送
        async function executeDelayedSend() {
            try {
                // 发送第一组数据
                await sendCommand(command1, '第一组数据已发送');
                
                // 立即发送第二组数据
                await sendCommand(command2, '第二组数据已发送');
                
                updateStatus('两组数据已全部发送完成', 'success');
                sendBtn.disabled = false;
                
            } catch (error) {
                updateStatus(`发送错误: ${error.message}`, 'error');
                console.error('发送错误:', error);
                sendBtn.disabled = false;
            }
        }
        
        // 发送单条命令
        async function sendCommand(command, successMessage) {
            const writer = port.writable.getWriter();
            await writer.write(new Uint8Array(command));
            updateStatus(successMessage + ': ' + arrayToHexString(command), 'success');
            writer.releaseLock();
        }
        
        // 断开连接按钮点击事件
        disconnectBtn.addEventListener('click', async () => {
            try {
                if (countdownInterval) {
                    clearInterval(countdownInterval);
                    countdownDiv.textContent = '';
                }
                
                if (reader) {
                    await reader.cancel();
                    reader = null;
                }
                
                if (port) {
                    await port.close();
                    port = null;
                }
                
                updateStatus('串口已断开', 'info');
                connectBtn.disabled = false;
                sendBtn.disabled = true;
                disconnectBtn.disabled = true;
                
            } catch (error) {
                updateStatus(`断开连接错误: ${error.message}`, 'error');
                console.error('断开连接错误:', error);
            }
        });
        
        // 读取串口数据
        async function readData() {
            try {
                while (port && port.readable) {
                    reader = port.readable.getReader();
                    
                    try {
                        while (true) {
                            const { value, done } = await reader.read();
                            if (done) break;
                            
                            const hexStr = arrayToHexString(Array.from(value));
                            receivedDataDiv.textContent = hexStr;
                            console.log('接收到数据:', hexStr);
                        }
                    } catch (readError) {
                        console.error('读取错误:', readError);
                    } finally {
                        reader.releaseLock();
                    }
                }
            } catch (error) {
                updateStatus(`读取数据错误: ${error.message}`, 'error');
                console.error('读取数据错误:', error);
            }
        }
        
        // 更新状态显示
        function updateStatus(message, type = 'info') {
            statusDiv.textContent = message;
            statusDiv.className = type;
        }
        
        // 将数组转换为16进制字符串
        function arrayToHexString(arr) {
            return arr.map(byte => byte.toString(16).padStart(2, '0').toUpperCase()).join(' ');
        }
    </script>
</body>
</html>